package com.example.base.security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.base.excetion.GlobalExcetion;
import com.example.base.security.domain.SysDept;
import com.example.base.security.domain.vo.SysDeptVo;
import com.example.base.security.mapper.SysDeptMapper;
import com.example.base.security.service.SysDeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author xiong
 * @since 2024-02-05
 */
@Service
@Transactional
@CacheConfig(cacheNames = "SysDeptServiceImpl")
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    @Cacheable(cacheNames = "sysdept",key = "#id")
    @Override
    public SysDept getById(Serializable id){
        return super.getById(id);
    }

    @CacheEvict(cacheNames = "sysdept", key = "#id")
    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @CacheEvict(cacheNames = "sysdept", key = "#sysdept.id")
    @Override
    public boolean updateById(SysDept sysdept) {
        return super.updateById(sysdept);
    }


    public SysDept saveOrUpdateSysDept(SysDeptVo sysDeptVo) throws GlobalExcetion {
        SysDept sysDept=new SysDept();
        BeanUtils.copyProperties(sysDeptVo,sysDept);
        if(sysDeptVo.getDeptPid()==null || 0==sysDeptVo.getDeptPid()){
            sysDeptVo.setDeptPid(0);
        }else {
            SysDept parent=getById(sysDeptVo.getDeptPid());
            if(parent==null){
                throw new GlobalExcetion(1,"父部门不存在");
            }
        }
        if(sysDeptVo.getId()!=null){
            SysDept entity=this.baseMapper.selectById(sysDeptVo.getId());
            if(entity==null){
                throw new GlobalExcetion(1,"部门不存在");
            }
            if(!entity.getDeptNo().equals(sysDeptVo.getDeptNo())){
                SysDept dept=getSysDeptByDeptNo(sysDeptVo.getDeptNo());
                if(dept!=null){
                    throw new GlobalExcetion(1,"部门编号已存在");
                }
            }
            this.baseMapper.updateById(sysDept);
        }else {
            SysDept dept=getSysDeptByDeptNo(sysDeptVo.getDeptNo());
            if(dept!=null){
                throw new GlobalExcetion(1,"部门编号已存在");
            }
            this.baseMapper.insert(sysDept);
        }
        return sysDept;
    }

    @CacheEvict(cacheNames = "sysdept", key = "#sysdept.id")
    public SysDept updateSysDeptById(SysDept sysdept){
        super.updateById(sysdept);
        return sysdept;
    }

    @Override
    public SysDept getSysDeptByDeptNo(String deptNo) {
        LambdaQueryWrapper<SysDept> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDept::getDeptNo,deptNo);
        return this.baseMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public List<SysDept> treeList() {
        List<SysDept> list=super.list();
        List<SysDept> array=new ArrayList<>();
        for (SysDept sysDept : list) {
            if(sysDept.getDeptPid()!=null && 0==sysDept.getDeptPid()){
                getTreeChild(sysDept,list);
                array.add(sysDept);
            }
        }
        return array;
    }

    @Override
    public List<SysDept> treeListById(Serializable id) {
        List<SysDept> treeList=treeList();
        List<SysDept> list=filterDataById(treeList,id);
        return list;
    }

    @Override
    public List<SysDept> childsById(Serializable id) {
        List<SysDept> treeList=treeList();
        List<SysDept> list=filterDataById(treeList,id);
        return flattenHierarchy(list);
    }

    @Override
    public List<SysDept> childsFilterChildById(Serializable id) {
        List<SysDept> treeList=treeList();
        SysDept sysDept=filterChildDataById(treeList,id);
        List<SysDept> sysDeptList=new ArrayList<>();
        sysDeptList.add(sysDept);
        return flattenHierarchy(sysDeptList);
    }

    // 根据ID过滤数据，保持原有层级结构不变
    private List<SysDept> filterDataById(List<SysDept> originalData, Serializable selectedId) {
        List<SysDept> result = new ArrayList<>();
        for (SysDept dept : originalData) {
            if (dept.getId() == selectedId) {
                result.add(dept);
                return result;
            } else if (dept.getChildren() != null && !dept.getChildren().isEmpty()) {
                SysDept filteredChild = filterDataById(dept.getChildren(), selectedId).stream().findFirst().orElse(null);
                if (filteredChild != null) {
                    result.add(dept);
                    result.get(result.size() - 1).setChildren(new ArrayList<>());
                    result.get(result.size() - 1).getChildren().add(filteredChild);
                    return result;
                }
            }
        }
        return result;
    }

    // 根据ID过滤数据，只返回自己及其子级结构，不返回父级结构
    private  SysDept filterChildDataById(List<SysDept> data, Serializable selectedId) {
        for (SysDept dept : data) {
            if (dept.getId() == selectedId) {
                return dept;
            } else if (dept.getChildren() != null && !dept.getChildren().isEmpty()) {
                SysDept filteredChild = filterChildDataById(dept.getChildren(), selectedId);
                if (filteredChild != null) {
                    return filteredChild;
                }
            }
        }
        return null;
    }


    // 将层级结构转换为普通List集合
    private List<SysDept> flattenHierarchy(List<SysDept> data) {
        List<SysDept> flattenedList = new ArrayList<>();
        for (SysDept dept : data) {
            flattenedList.add(dept);
            if (dept.getChildren() != null && !dept.getChildren().isEmpty()) {
                flattenedList.addAll(flattenHierarchy(dept.getChildren()));
            }
        }
        return flattenedList;
    }





    private static void getTreeChild(SysDept entity, List<SysDept> list){
        for (SysDept dept : list){
            if(dept.getDeptPid() !=null && dept.getDeptPid().equals(entity.getId())){
                if(entity.getChildren()==null){
                    entity.setChildren(new ArrayList<>());
                }
                entity.getChildren().add(dept);
                getTreeChild(dept,list);
            }
        }
    }


}
